/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package documentweighting;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import queryterm.QueryTerm;
import retrieval.DocumentModel;
import retrieval.ListDocument;

/**
 *
 * @author Zakiy Firdaus
 */
public class BM25 {
    private HashMap<String,Integer> docFrequency;
    
    private boolean queryFound;
    
    public BM25(ArrayList<QueryTerm> aqt, ListDocument ld){
        docFrequency = new HashMap<String, Integer>();
        int jumlahSearch=0,j;
        for (QueryTerm t : aqt) {
            String add = t.getToken()+":"+t.getField();
            j = ld.getDocumentFrequencyByQuery(t.getToken(), t.getField());
            docFrequency.put(add, j);
            jumlahSearch+=j;
        }
        if (jumlahSearch==0) {
            queryFound = false;
        } else {
            queryFound = true;
        }
    }
    
    public void getBM25Weight(double k1, double k2, double b, 
            ArrayList<QueryTerm> aqt, ListDocument ld){
    //--------------------    
        HashMap<Integer,DocumentModel> listDocs = ld.getListDocument();
        int N = ld.getJumlahDokumen();
        double avgdoclength = ld.getAvgDocumentLength();
        
        Iterator it = listDocs.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pairs = (Map.Entry) it.next();
            DocumentModel dm = (DocumentModel)pairs.getValue();
            long doclength = dm.getDocLength();
            double K = k1*((1-b)+(b*doclength/avgdoclength));
            double docWeight=0;
            for(QueryTerm qt:aqt){
                int tf = dm.getQueryTF(qt.getToken(),qt.getField());
                double qf = qt.getWeight();
                if (tf!=0 && qf!=0) {
                    int n = getDocFrequency().get(qt.getToken()+":"+qt.getField());
                    double tempLog = (1/((n+0.5)/(N-n+0.5)));
                    tempLog = Math.log10(tempLog);
                    double temp1 = ((k1+1)*tf/(K+tf));
                    double temp2 = ((k2+1)*qf/(k2+qf));
                    docWeight+=(tempLog*temp1*temp2);
                }
            }
            dm.setWeight(docWeight);
        }
    }
    

    /**
     * @return the docFrequency
     */
    public HashMap<String,Integer> getDocFrequency() {
        return docFrequency;
    }

    /**
     * @return the isQueryFound
     */
    public boolean isIsQueryFound() {
        return queryFound;
    }

    /**
     * @param isQueryFound the isQueryFound to set
     */
    public void setIsQueryFound(boolean isQueryFound) {
        this.queryFound = isQueryFound;
    }
}
